package com.zmj.sy.mom.srv.aps.service;

import cn.hutool.core.collection.CollUtil;
import com.zmj.sy.mom.srv.aps.bean.entity.order.ApsWorkDetail;
import com.zmj.sy.mom.srv.aps.bean.entity.order.ApsWorkOrder;
import com.zmj.sy.mom.srv.aps.bean.entity.order.Order;
import com.zmj.sy.mom.srv.aps.bean.vo.base.BaseListResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.team.TeamReportDataPhaseResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.team.TeamReportDataResVo;
import com.zmj.sy.mom.srv.aps.bean.vo.team.TeamReportReqVo;
import com.zmj.sy.mom.srv.aps.bean.vo.team.TeamReportResVo;
import com.zmj.sy.mom.srv.aps.mapper.ApsWorkDetailMapper;
import com.zmj.sy.mom.srv.aps.mapper.ApsWorkOrderMapper;
import com.zmj.sy.mom.srv.aps.mapper.OrderMapper;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.util.*;
import java.util.stream.Collectors;

@RequiredArgsConstructor
@Service
public class TeamService {

    private final OrderMapper orderMapper;
    private final ApsWorkOrderMapper apsWorkOrderMapper;
    private final ApsWorkDetailMapper apsWorkDetailMapper;

    @Transactional(readOnly = true)
    public BaseListResVo<TeamReportResVo> report(TeamReportReqVo reqVo) {

        if(!StringUtils.hasText(reqVo.getConstructNo())){
            return BaseListResVo.empty();
        }
        if(CollUtil.isEmpty(reqVo.getPhaseCodeList())){
           return BaseListResVo.empty();
        }


        List<Order> orderList = orderMapper.lambdaQuery().eq(Order::getOrderType, 1)
                .likeRight(Order::getConstructNo, reqVo.getConstructNo())
                .list();
        if(CollUtil.isEmpty(orderList)){
            return BaseListResVo.empty();
        }

        List<TeamReportResVo> resVoList = new ArrayList<>();

        Optional<Order> ceban = orderList.stream().filter(e -> e.getMaterName().contains("侧板")).findFirst();
        if(ceban.isPresent()){
            Order order = ceban.get();

            List<ApsWorkOrder> apsWorkOrderList = apsWorkOrderMapper.lambdaQuery()
                    .eq(ApsWorkOrder::getOrderId, order.getId())
                    .eq(ApsWorkOrder::getMaterType, "Platepart")
                    .list();

            Map<String, TeamReportDataResVo> map = apsWorkOrderList.stream()
                    .map(e -> {
                        TeamReportDataResVo data = new TeamReportDataResVo();
                        data.setPlmId(e.getPlmId());
                        data.setMaterName(e.getMaterName());
                        data.setTotalCount(e.getOrderCount().intValue());
                        return data;
                    })
                    .collect(Collectors.toMap(TeamReportDataResVo::getPlmId, e -> e, (a, b) -> {
                        a.setTotalCount(a.getTotalCount() + b.getTotalCount());
                        return a;
                    }));

            TeamReportResVo r = new TeamReportResVo();
            r.setAssemblyPlmId(order.getPlmId());
            r.setAssemblyMaterName("侧板");
            r.setTotalCount(order.getOrderQty());
            r.getData().addAll(map.values());
            resVoList.add(r);

            if(CollUtil.isNotEmpty(r.getData())){
                List<String> collect = r.getData().stream().map(TeamReportDataResVo::getPlmId).distinct().collect(Collectors.toList());
                // 所有的工件
//                apsWorkOrderMapper.lambdaQuery().list();

                List<ApsWorkDetail> assWorkDetailList = apsWorkDetailMapper.lambdaQuery()
                        .eq(ApsWorkDetail::getOrderId, order.getId())
                        .eq(ApsWorkDetail::getPlmId, collect)
                        .in(ApsWorkDetail::getPhaseCode, reqVo.getPhaseCodeList())
                        .list();

                Map<String, ApsWorkDetail> collect1 = assWorkDetailList.stream()
                        .collect(Collectors.toMap(e -> e.getPhaseCode().replaceAll("\\d{2}$", ""), e -> e, (a, b) -> {
                            a.setTotalCount(a.getTotalCount().add(b.getTotalCount()));
                            return a;
                        }));


                // 所有工序
                List<TeamReportDataPhaseResVo> collect2 = collect1.values()
                        .stream()
                        .map(e -> {
                            TeamReportDataPhaseResVo rrr = new TeamReportDataPhaseResVo();
                            rrr.setPhaseCode(e.getPhaseCode());
                            rrr.setPhaseName(e.getPhaseName());
                            rrr.setFinishCount(e.getFinishCount().intValue());
                            return rrr;
                        }).collect(Collectors.toList());





            }


        }

        String assPattern = ".+(P[1-6]_170|PDB_170)$";
        List<Order> sandajianList = orderList.stream().filter(e -> !e.getMaterName().contains("侧板")).collect(Collectors.toList());
        for (Order order : sandajianList) {
            if (order.getOrderStatus() < 6) {
                continue;
            }

            List<ApsWorkOrder> apsWorkOrderList = apsWorkOrderMapper.lambdaQuery()
                    .eq(ApsWorkOrder::getOrderId, order.getId())
                    .list();

            List<ApsWorkOrder> assWorkOrderList = apsWorkOrderList.stream()
                    .filter(e -> e.getPlmId().matches(assPattern))
                    .sorted(Comparator.comparing(ApsWorkOrder::getLevel))
                    .collect(Collectors.toList());

            Map<String, ApsWorkOrder> apsWorkOrderMap = assWorkOrderList.stream().collect(Collectors.toMap(ApsWorkOrder::getPlmId, e -> e, (a, b) -> {
                a.setOrderCount(a.getOrderCount().add(b.getOrderCount()));
                return a;
            }));

            Map<Integer, List<ApsWorkOrder>> pidMap = apsWorkOrderList.stream()
                    .filter(e -> e.getBomPid() != null)
                    .filter(e -> !e.getPlmId().matches(assPattern))
                    .collect(Collectors.groupingBy(ApsWorkOrder::getBomPid));

            List<TeamReportResVo> collect = apsWorkOrderMap.values()
                    .stream()
                    .sorted(Comparator.comparing(ApsWorkOrder::getOrderId).thenComparing(ApsWorkOrder::getLevel).reversed())
                    .map(e -> {
                        TeamReportResVo r = new TeamReportResVo();
                        r.setAssemblyPlmId(e.getPlmId());
                        r.setAssemblyMaterName(e.getMaterName());
                        r.setTotalCount(e.getOrderCount().intValue());
                        List<ApsWorkOrder> apsWorkOrders = new ArrayList<>();
                        apsWorkOrders.add(e);

                        List<TeamReportDataResVo> all = new ArrayList<>();

                        while(true){
                            if (CollUtil.isEmpty(apsWorkOrders)) {
                                break;
                            }


                            List<ApsWorkOrder> tempList = new ArrayList<>();
                            for (ApsWorkOrder apsWorkOrder : apsWorkOrders) {
                                List<ApsWorkOrder> childrenList = pidMap.get(apsWorkOrder.getBomId());
                                if(CollUtil.isNotEmpty(childrenList)){
                                    tempList.addAll(childrenList);
                                    List<ApsWorkOrder> collect1 = childrenList.stream().filter(c -> c.getWorkChain().contains("JG") || c.getWorkChain().contains("HG")).collect(Collectors.toList());
                                    if(CollUtil.isNotEmpty(collect1)){
                                        List<TeamReportDataResVo> collect2 = collect1.stream().map(f -> {
                                            TeamReportDataResVo data = new TeamReportDataResVo();
                                            data.setPlmId(f.getPlmId());
                                            data.setMaterName(f.getMaterName());
                                            data.setTotalCount(f.getOrderCount().intValue());
                                            return data;
                                        }).collect(Collectors.toList());
                                        all.addAll(collect2);
                                    }

                                }

                            }

                            apsWorkOrders = tempList;

                        }

                        Map<String, TeamReportDataResVo> map = all.stream().collect(Collectors.toMap(TeamReportDataResVo::getPlmId, e1 -> e1, (a, b) -> {
                            a.setTotalCount(a.getTotalCount() + b.getTotalCount());
                            return a;
                        }));

                        if (CollUtil.isNotEmpty(map)) {
                            r.getData().addAll(map.values());
                        }

                        return r;
                    })
                    .collect(Collectors.toList());



            resVoList.addAll(collect);

        }



        return new BaseListResVo<>(resVoList);
    }
}
